# -*- coding: utf-8 -*-
# 处理字符串、数字转换等基础函数
# @Time    ：2024/4/9 10:23
# @Author  ：徐良
# @File    ：baseFunction.py

from PySide6.QtCore import QDate, QTime, QDateTime
from typing import Any, List, Optional, Union
from datetime import datetime
import re

def quote(string: str) -> str:
    """
    返回带单引号的字符串。

    Args:
        string (str): 输入的字符串。

    Returns:
        str: 加了单引号的字符串，例如 `'abc'`。
    """
    # 使用 format 或 f-string 为字符串添加单引号
    return "'{}'".format(string)


def get_number_round(num: float, decimal: Optional[int] = None) -> float:
    """
    返回浮点数的四舍五入结果，保留指定的小数位。

    Args:
        num (float): 输入的浮点数。
        decimal (Optional[int], optional): 保留的小数位数，支持 0~4，默认保留 2 位。

    Returns:
        float: 四舍五入后的数值。
    """
    # 根据 decimal 决定格式化字符串，控制小数位数
    if decimal is None:
        format_str = "{:.2f}"
    elif decimal in [0, 1, 2, 3, 4]:
        format_str = f"{{:.{decimal}f}}"
    else:
        format_str = "{:.2f}"  # 超出范围默认保留两位

    return float(format_str.format(num))


def check_str_date(str_date: Union[str, None]) -> str:
    """
    检查并规范化日期字符串，最终返回 yyyy-MM-dd 格式：
    1. 如果 str_date 是 None 或空字符串，返回默认值 '2000-01-01'
    2. 支持以下格式自动转换（月份名称大小写不敏感）：
       - 标准格式：yyyy-MM-dd, yy-MM-dd, yyyy/MM/dd, yyyy.MM.dd
       - 英文格式：d-Mon-yyyy, Mon d, yyyy（如 5-May-2023 或 May 5, 2023）
    3. 其他无法解析的格式返回默认值 '2000-01-01'

    参数:
        str_date: 待处理的日期字符串（允许None或空字符串）

    返回:
        规范化的 yyyy-MM-dd 格式日期字符串
    """
    if not str_date:  # 处理 None 或空字符串
        return '2000-01-01'

    # 预处理：统一处理点分隔符和大小写问题
    normalized_date = str_date.replace('.', '-').title()  # 将点转为横杠并规范大小写

    # 支持的日期格式列表（按解析效率排序）
    date_formats = [
        '%Y-%m-%d',  # yyyy-MM-dd
        '%y-%m-%d',  # yy-MM-dd
        '%Y/%m/%d',  # yyyy/MM/dd
        '%d-%b-%Y',  # d-Mon-yyyy（5-May-2023）
        '%b-%d-%Y',  # Mon-d-yyyy（May-5-2023）
        '%d-%B-%Y',  # d-MonthName-yyyy（5-May-2023）
        '%B-%d-%Y',  # MonthName-d-yyyy（May-5-2023）
        '%b %d, %Y',  # Mon d, yyyy（May 5, 2023）
        '%B %d, %Y',  # MonthName d, yyyy（May 5, 2023）
    ]

    for fmt in date_formats:
        try:
            dt = datetime.strptime(normalized_date, fmt)
            return dt.strftime('%Y-%m-%d')
        except ValueError:
            continue

    # 特殊处理：美国格式 MM/dd/yyyy
    if re.match(r'^\d{1,2}/\d{1,2}/\d{4}$', str_date):
        try:
            dt = datetime.strptime(str_date, '%m/%d/%Y')
            return dt.strftime('%Y-%m-%d')
        except ValueError:
            pass

    # 所有格式尝试失败后返回默认值
    return '2000-01-01'


def check_str_datetime(datetime_str: Union[str, None]) -> str:
    """
    检查并规范化日期时间字符串，最终返回 yyyy-MM-dd HH:mm:ss 格式：
    1. 如果 datetime_str 是 None 或空字符串，返回默认值 '2000-01-01 00:00:00'
    2. 支持以下格式自动转换（月份名称大小写不敏感）：
       - 日期格式：yyyy-MM-dd, yy-MM-dd, yyyy/MM/dd, yyyy.MM.dd, d-Mon-yyyy 等
       - 日期时间格式：yyyy-MM-dd HH:mm:ss, yyyy/MM/dd HH:mm:ss 等
    3. 其他无法解析的格式返回默认值 '2000-01-01 00:00:00'

    参数:
        datetime_str: 待处理的日期时间字符串（允许None或空字符串）

    返回:
        规范化的 yyyy-MM-dd HH:mm:ss 格式字符串
    """
    if not datetime_str:  # 处理 None 或空字符串
        return '2000-01-01 00:00:00'

    # 预处理：统一处理点分隔符和大小写问题
    normalized_str = datetime_str.replace('.', '-').title()

    # 支持的日期时间格式列表（按解析效率排序）
    datetime_formats = [
        '%Y-%m-%d %H:%M:%S',  # 标准日期时间格式
        '%y-%m-%d %H:%M:%S',  # 短年份日期时间格式
        '%Y/%m/%d %H:%M:%S',  # 斜杠分隔日期时间
        '%Y-%m-%d',  # 纯日期格式（自动补零时时间）
        '%y-%m-%d',  # 短年份纯日期
        '%Y/%m/%d',  # 斜杠分隔纯日期
        '%d-%b-%Y %H:%M:%S',  # 英文月份日期时间（5-May-2023 12:30:45）
        '%b %d, %Y %H:%M:%S',  # May 5, 2023 12:30:45
        '%m/%d/%Y %H:%M:%S',  # 美国格式日期时间
    ]

    for fmt in datetime_formats:
        try:
            dt = datetime.strptime(normalized_str, fmt)
            return dt.strftime('%Y-%m-%d %H:%M:%S')
        except ValueError:
            continue

    # 特殊处理：没有时间部分的情况自动补零
    date_only_formats = [
        '%Y-%m-%d', '%y-%m-%d', '%Y/%m/%d',
        '%d-%b-%Y', '%b %d, %Y', '%m/%d/%Y'
    ]

    for fmt in date_only_formats:
        try:
            dt = datetime.strptime(normalized_str, fmt)
            return dt.strftime('%Y-%m-%d 00:00:00')  # 补全时间部分
        except ValueError:
            continue

    # 所有格式尝试失败后返回默认值
    return '2000-01-01 00:00:00'


def check_str_time(time_str: Union[str, None]) -> str:
    """
    检查并规范化时间字符串，最终返回 HH:mm:ss 格式（24小时制）：
    1. 如果 time_str 是 None 或空字符串，返回默认值 '00:00:00'
    2. 支持以下格式自动转换：
       - 24小时制：
         - HH:mm:ss / H:mm:ss / HH:mm / H:mm
         - HHmmss / HHmm
       - 12小时制（带AM/PM）：
         - h:mm:ss AM / h:mm:ss PM
         - h:mm AM / h:mm PM
         - hmmssAM / hmmssPM
    3. 自动处理中英文符号和大小写（如"02:30下午"或"2:30pm"）
    4. 其他无法解析的格式返回默认值 '00:00:00'

    参数:
        time_str: 待处理的时间字符串（允许None或空字符串）

    返回:
        规范化的 HH:mm:ss 格式字符串（24小时制）
    """
    if not time_str:  # 处理 None 或空字符串
        return '00:00:00'

    # 预处理步骤（关键改进点）
    normalized_str = time_str.strip().upper()

    # 转换中文标识（如"下午"→"PM"）
    normalized_str = (normalized_str.replace('上午', 'AM')
                      .replace('下午', 'PM')
                      .replace('中午', 'PM')
                      .replace('凌晨', 'AM'))

    # 统一符号和空格（处理如"02：30PM"或"02-30-PM"等情况）
    normalized_str = re.sub(r'[^\w]', ' ', normalized_str)  # 非字母数字转空格
    normalized_str = re.sub(r'\s+', ' ', normalized_str).strip()

    # 支持的时间格式列表（优先级从高到低）
    time_formats = [
        # 24小时制格式
        '%H:%M:%S', '%H:%M', '%H%M%S', '%H%M',

        # 12小时制格式（带AM/PM）
        '%I:%M:%S %p', '%I:%M %p', '%I%M%S%p', '%I%M%p',

        # 特殊兼容格式（如"2:30PM"无空格）
        '%I:%M%p', '%I%M%p'
    ]

    for fmt in time_formats:
        try:
            dt = datetime.strptime(normalized_str, fmt)
            return dt.strftime('%H:%M:%S')  # 统一转为24小时制输出
        except ValueError:
            continue

    # 特殊处理：纯数字（如"1430"→"14:30:00"）
    if re.match(r'^\d+$', normalized_str):
        digits = normalized_str.ljust(6, '0')[:6]  # 补全到6位数字
        try:
            dt = datetime.strptime(digits, '%H%M%S')
            return dt.strftime('%H:%M:%S')
        except ValueError:
            pass

    return '00:00:00'



